package com.salton123.processor.action

import com.salton123.processor.util.log
import com.squareup.kotlinpoet.ClassName
import tv.athena.annotation.ModuleInitializer
import javax.annotation.processing.ProcessingEnvironment
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
import javax.lang.model.type.DeclaredType
import javax.lang.model.util.ElementFilter
import javax.tools.Diagnostic

/**
 * @Time:2021/2/4 10:51
 * @Author:wujinsheng
 * @Description:
 * 如果kotlin版本为1.3.50会有bug
 */
class ModuleInitializerProcessDispatch : IProcessDispatch {
    private lateinit var mProcessingEnv: ProcessingEnvironment
    private val mFunMap: HashMap<TypeElement, HashSet<TypeElement>> = HashMap()
    private val I_MODULE_INIT_PRIORITY = ClassName.bestGuess("com.salton123.module.api.IBornAction")
    override fun process(roundEnv: RoundEnvironment?, processingEnv: ProcessingEnvironment) {
        this.mProcessingEnv = processingEnv
        note("roundEnv:$roundEnv,processingEnv:$processingEnv")
        ElementFilter.typesIn(roundEnv?.getElementsAnnotatedWith(ModuleInitializer::class.java))
            .forEachIndexed { index, typeElement ->
                log(typeElement.toString())
                if (!typeElement.modifiers.contains(Modifier.PUBLIC)) {
                    val reason = "${typeElement.enclosingElement.simpleName}必须为public\n"
                    error(reason)
                }
                val typeList = typeElement.interfaces.map { (it as DeclaredType).asElement().toString() }
                val hasImplmentInterface = typeList.contains(I_MODULE_INIT_PRIORITY.toString())
                if (!hasImplmentInterface) {
                    val reason = "${typeElement.enclosingElement.simpleName}必须实现IBornAction\n"
                    error(reason)
                } else {

                }

                println(typeElement.superclass)
                note("ProcessorAction ${typeElement.superclass}")
            }
    }

    private fun note(msg: String) {
        mProcessingEnv.messager.printMessage(Diagnostic.Kind.NOTE, "[ProcessDispather] $msg")
        log(msg)
    }

    private fun error(msg: String) {
        mProcessingEnv.messager.printMessage(Diagnostic.Kind.ERROR, msg)
    }

    private fun isPublic(element: ExecutableElement): Boolean {
        return element.modifiers.contains(Modifier.PUBLIC)
    }
}

